﻿using System;
using System.Collections.Generic;
using System.IO;

namespace Dexter.Storage {
	public interface IStorageProvider {
		/// <summary>
		/// Retrieves the public URL for a given file within the storage provider.
		/// </summary>
		/// <param name="path">The relative path within the storage provider.</param>
		/// <returns>The public URL.</returns>
		string GetPublicUrl ( string path );

		/// <summary>
		/// Retrieves a file within the storage provider.
		/// </summary>
		/// <param name="path">The relative path to the file within the storage provider.</param>
		/// <returns>The file.</returns>
		/// <exception cref="FileNotFoundException">If the file is not found.</exception>
		IStorageFile GetFile ( string path );

		/// <summary>
		/// Check if the specified file exists.
		/// </summary>
		/// <param name="path">The path.</param>
		/// <returns><c>True</c> if the file exists into the repository. Otherwise <c>false</c>.</returns>
		bool FileExist ( string path );

		/// <summary>
		/// Lists the files within a storage provider's path.
		/// </summary>
		/// <param name="path">The relative path to the folder which files to list.</param>
		/// <returns>The list of files in the folder.</returns>
		IEnumerable<IStorageFile> ListFiles ( string path );

		/// <summary>
		/// Lists the folders within a storage provider's path.
		/// </summary>
		/// <param name="path">The relative path to the folder which folders to list.</param>
		/// <returns>The list of folders in the folder.</returns>
		IEnumerable<IStorageFolder> ListFolders ( string path );

		/// <summary>
		/// Gets the folder.
		/// </summary>
		/// <param name="path">The path.</param>
		/// <returns></returns>
		IStorageFolder GetFolder ( string path );

		/// <summary>
		/// Folders the exists.
		/// </summary>
		/// <param name="path">The path.</param>
		/// <returns></returns>
		bool FolderExists ( string path );

		/// <summary>
		/// Tries to create a folder in the storage provider.
		/// </summary>
		/// <param name="path">The relative path to the folder to be created.</param>
		/// <returns>True if success; False otherwise.</returns>
		bool TryCreateFolder ( string path );

		/// <summary>
		/// Creates a folder in the storage provider.
		/// </summary>
		/// <param name="path">The relative path to the folder to be created.</param>
		/// <exception cref="ArgumentException">If the folder already exists.</exception>
		void CreateFolder ( string path );

		/// <summary>
		/// Deletes a folder in the storage provider.
		/// </summary>
		/// <param name="path">The relative path to the folder to be deleted.</param>
		/// <exception cref="ArgumentException">If the folder doesn't exist.</exception>
		void DeleteFolder ( string path );

		/// <summary>
		/// Renames a folder in the storage provider.
		/// </summary>
		/// <param name="oldPath">The relative path to the folder to be renamed.</param>
		/// <param name="newPath">The relative path to the new folder.</param>
		void RenameFolder ( string oldPath, string newPath );

		/// <summary>
		/// Deletes a file in the storage provider.
		/// </summary>
		/// <param name="path">The relative path to the file to be deleted.</param>
		/// <exception cref="ArgumentException">If the file doesn't exist.</exception>
		void DeleteFile ( string path );

		/// <summary>
		/// Renames a file in the storage provider.
		/// </summary>
		/// <param name="oldPath">The relative path to the file to be renamed.</param>
		/// <param name="newPath">The relative path to the new file.</param>
		void RenameFile ( string oldPath, string newPath );

		/// <summary>
		/// Creates a file in the storage provider.
		/// </summary>
		/// <param name="path">The relative path to the file to be created.</param>
		/// <exception cref="ArgumentException">If the file already exists.</exception>
		/// <returns>The created file.</returns>
		IStorageFile CreateFile ( string path );

		/// <summary>
		/// Tries to save a stream in the storage provider.
		/// </summary>
		/// <param name="path">The relative path to the file to be created.</param>
		/// <param name="inputStream">The stream to be saved.</param>
		/// <returns>True if success; False otherwise.</returns>
		bool TrySaveStream ( string path, Stream inputStream );

		/// <summary>
		/// Saves a stream in the storage provider.
		/// </summary>
		/// <param name="path">The relative path to the file to be created.</param>
		/// <param name="inputStream">The stream to be saved.</param>
		/// <exception cref="ArgumentException">If the stream can't be saved due to access permissions.</exception>
		void SaveStream ( string path, Stream inputStream );

		/// <summary>
		/// Combines to paths.
		/// </summary>
		/// <param name="path1">The parent path.</param>
		/// <param name="path2">The child path.</param>
		/// <returns>The combined path.</returns>
		string Combine ( string path1, string path2 );

		/// <summary>
		/// Gets the get private root.
		/// </summary>
		/// <value>The get private root.</value>
		string PrivateRoot { get; }

		/// <summary>
		/// Gets the get public root.
		/// </summary>
		/// <value>The get public root.</value>
		string PublicRoot { get; }
	}
}